package com.sniper.web.action.admin;

import com.sniper.config.Global;
import com.sniper.model.SystemConfig;
import com.sniper.mybatis.service.impl.SystemConfigService;
import com.sniper.utils.DataUtil;
import com.sniper.utils.PageUtil;
import com.sniper.utils.ValidateUtil;
import com.sniper.web.searchUtils.AdminGroupSearch;
import com.sniper.web.utils.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.quartz.SchedulerException;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author sniper
 */
@Controller
@RequestMapping(value = "${adminPath}/admin-config")
public class AdminConfigController extends AdminBaseController {

    @Resource
    QuartzManagerUtil quartzManagerUtil;

    @Resource
    private SystemConfigService configService;


    @RequiresPermissions("admin:config:view")
    @RequestMapping("/")
    public String index(Map<String, Object> map, AdminGroupSearch search) {

        map.put("groupSearch", search);

        ParamsToHtml toHtml = new ParamsToHtml();
        toHtml.setSniperUrl("/admin-config/delete");

        Map<String, String> menu = new HashMap<>();
        menu.put("true", "是");
        menu.put("false", "否");

        toHtml.addMapValue("autoload", menu);
        Map<String, String> keys = new HashMap<>();
        keys.put("autoload", "自动加载");

        toHtml.setKeys(keys);
        Map<String, Object> params = new HashMap<>();
        if (ValidateUtil.isValid(search.getAutoload())) {
            params.put("autoload", search.getAutoload());
        }
        params.put("order", "id desc");
        PageUtil<SystemConfig> page = configService.page(request, search.getLimit(), params);
        List<SystemConfig> lists = page.getLists();
        for (SystemConfig systemConfig : lists) {
            if (systemConfig.getKeyName().equals("rootDir")) {
                systemConfig.setKeyInfo(systemConfig.getKeyInfo() + ",系统获取的参考路径:" + FilesUtil.getRootDir());
            }
        }
        page.setLists(lists);
        map.put("page", page);
        map.put("sniperMenu", toHtml);
        return forward("/admin/admin-config/index.jsp");
    }

    @RequiresPermissions("admin:config:insert")
    @RequestMapping(value = "insert", method = RequestMethod.GET)
    public String insert(Map<String, Object> map) {
        map.put("config", new SystemConfig());
        return forward("/admin/admin-config/save-input.jsp");
    }

    @ResponseBody
    @RequiresPermissions("admin:config:insert")
    @RequestMapping(value = "insert", method = RequestMethod.POST)
    public ControllerUtils.CallBackResult insert(@Validated SystemConfig config, BindingResult result) {

        return new ControllerUtils().ajaxPostResult(result, callBackResult -> {
            config.setId(FilesUtil.UUID());
            configService.insert(config);
            return callBackResult;
        });
    }

    @RequiresPermissions("admin:config:update")
    @RequestMapping(value = "update", method = RequestMethod.GET)
    public String update(@RequestParam(value = "id", required = false) String id, Map<String, Object> map) {
        SystemConfig config = configService.get(id);

        map.put("config", config);
        return forward("/admin/admin-config/save-input.jsp");
    }

    @ResponseBody
    @RequiresPermissions("admin:config:update")
    @RequestMapping(value = "update", method = RequestMethod.POST)
    public ControllerUtils.CallBackResult update(@Validated SystemConfig config, BindingResult result) {
        return new ControllerUtils().ajaxPostResult(result, callBackResult -> {
            configService.update(config);
            return callBackResult;
        });
    }

    @RequiresPermissions("admin:config:delete")
    @ResponseBody
    @RequestMapping(value = "delete", method = RequestMethod.POST)
    public Map<String, Object> delete(@RequestParam("delid") String[] delid, @RequestParam("menuType") String menuType,
                                      @RequestParam("menuValue") String menuValue) {
        Map<String, Object> ajaxResult = new HashMap<>();
        switch (menuType) {
            case "delete":
                ControllerUtils.delete(ajaxResult, configService, delid);
                break;
            case "autoload":
                try {
                    for (String string : delid) {
                        SystemConfig config = configService.get(string);
                        config.setAutoload(DataUtil.stringToBoolean(menuValue));
                        configService.update(config);
                    }
                    ajaxResult.put("code", 1);
                    ajaxResult.put("msg", "success");
                } catch (Exception e) {
                    ajaxResult.put("code", -1);
                    ajaxResult.put("msg", e.getMessage());
                }
                break;
            default:
                break;
        }
        return ajaxResult;
    }

    /**
     * 操作
     *
     * @author suzhen
     */
    public static final class KeyMap {
        final Map<Integer, String> keyMap = new LinkedHashMap<>();

        {
            keyMap.put(1, "系统: 更新左侧菜单。");
            keyMap.put(2, "系统: 更新系统配置。");
            keyMap.put(3, "Html: 更新首页缓存。");
            keyMap.put(100, "Redis: 清空当前数据库");
            keyMap.put(101, "Redis: 清空所有数据库");
            keyMap.put(200, "Properties: 重置Properties文件");

        }

        public Map<Integer, String> getKeyMap() {
            return keyMap;
        }

        public String getValue(Integer key) {
            if (keyMap.containsKey(key)) {
                return keyMap.get(key);
            }
            return "";
        }
    }

    @RequiresPermissions("admin:config:cache")
    @RequestMapping(value = "cache", method = RequestMethod.GET)
    public String cache(Map<String, Object> map) {
        map.put("keyMap", new KeyMap());
        return site.getName() + "/admin/admin-config/cache.ftl";
    }

    /**
     * @param map
     * @param clearType
     * @return
     * @throws InterruptedException
     * @throws SchedulerException
     */
    @RequiresPermissions("admin:config:cache")
    @RequestMapping(value = "cache", method = RequestMethod.POST)
    public String cache(Map<String, Object> map, @RequestParam("clearType") Integer[] clearType)
            throws InterruptedException, SchedulerException {
        // 清空tree菜单数据
        // 数据排序
        List<String> result = new ArrayList<>();
        Arrays.sort(clearType);
        // 数组查询位置,返回其位置索引
        if (Arrays.binarySearch(clearType, 1) > -1) {
            try {
                // 清空菜单数据
                // 清空redis存放的已经生成的数据,清空所有用户组的列表
                getzTreeMenuData().clear();
                result.add("左侧菜单:" + new KeyMap().keyMap.get(1) + "<a href=\"" + adminPath.substring(1)
                        + "/admin-config/cache\">[执行]后点击我</a>:操作成功");
            } catch (Exception e) {
                e.printStackTrace();
                result.add(e.getMessage());
            }
        }

        // 操作系统配置
        if (Arrays.binarySearch(clearType, 2) > -1) {
            SystemConfigUtil.clear();
            SystemConfigUtil.init();
            result.add(new KeyMap().keyMap.get(2) + ":操作成功");
        }

        if (Arrays.binarySearch(clearType, 3) > -1) {
            result.add(new KeyMap().keyMap.get(3) + ":操作成功");
        }

        if (Arrays.binarySearch(clearType, 100) > -1) {
            redisConn.flushDB();
            result.add(new KeyMap().keyMap.get(100) + ":操作成功");
        }

        if (Arrays.binarySearch(clearType, 101) > -1) {
            redisConn.flushAll();
            result.add(new KeyMap().keyMap.get(101) + ":操作成功");
        }

        if (Arrays.binarySearch(clearType, 200) > -1) {
            Global.reset();
            result.add(new KeyMap().keyMap.get(200) + ":操作成功");
        }

        map.put("keyMap", new KeyMap());
        map.put("result", result);
        return site.getName() + "/admin/admin-config/cache.ftl";
    }
}